﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Sdg.Domain.Services
{
    public class SqlScriptBuilder : IScriptBuilder
    {
        private BizObj.TableSettings _table;
        private int _commitAfter;


        public int CommitAfter
        {
            get
            {
                return _commitAfter;
            }
            set
            {
                if (value < 1)
                    throw new ArgumentOutOfRangeException("CommitAfter должен быть больше 0");

                SetCommitAfter(value);
            }
        }

        private void SetCommitAfter(int value)
        {
            if (_table == null)
            {

                _commitAfter = value;
            }
            else
            {
                _commitAfter = _table.NewRowCount <= value ? _table.NewRowCount : value;
            }
        }

        public void SetTable(BizObj.TableSettings table)
        {
            _table = table;
            SetCommitAfter(_commitAfter);
        }

        public string GetScript()
        {
            StringBuilder script = new StringBuilder(1024);

            int currentRowNum = 0;
            int totalRows = _table.NewRowCount;
            // очистка таблицы
            WriteScriptHeader(script);

            int partCount = (int)Math.Ceiling(_table.NewRowCount / (double)_commitAfter);
            int countInPart = _table.NewRowCount / _commitAfter;

            for (int i = 0; i < totalRows; i++)
            {
                currentRowNum++;
                var commit = currentRowNum >= countInPart;
                AddInsertCommand(script, commit);

                if (commit)
                    currentRowNum = 0;
            }

            script.Append("commit tran;");
            //var l = "begin tran;".Length;
           // script.Remove(script.Length - l, l);

            return script.ToString();
        }
        
        private void AddInsertCommand(StringBuilder script, bool commit)
        {
            string tmpl = @"insert into " + _table.Name + "({0}) values({1});";
            var fields = string.Join(",", _table.Columns.Where(c => !c.IsIdentity).Select(c => c.Name));

            var vals = string.Join(",", _table.Columns.Where(c => !c.IsIdentity).Select(c => "'" + c.DataGenerator.Next() + "'"));

            script.AppendFormat(tmpl, fields, vals)
                .AppendLine();

            if (commit)
                script.AppendLine("commit tran;")
                    .AppendLine("begin tran;");
        }

        private void WriteScriptHeader(StringBuilder script)
        {
            if (_table.ClearBeforeFilling)
                script.AppendFormat("delete from {0};", _table.Name).AppendLine();

            script.AppendLine("begin tran;");
        }


    }
}
